package com.jsbj.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsbj.page.PageDomain;
import com.jsbj.page.TableSupport;
import com.jsbj.tools.BeanUtils;
import com.jsbj.tools.ChineseCharacterUtil;
import com.jsbj.tools.RequestHeaderUtils;
import com.jsbj.tools.StringUtils;
import com.jsbj.user.entities.*;
import com.jsbj.user.mapper.SysRoleMapper;
import com.jsbj.user.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 角色信息表 服务实现类
 * </p>
 *
 * @author jsbj
 * @since 2022-03-07
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ISysRoleOrgService sysRoleOrgService;

    @Autowired
    private ISysRoleUserService sysRoleUserService;

    @Autowired
    private ISysRoleEquService sysRoleEquService;

    @Autowired
    private ISysRolePermissionService sysRolePermissionService;

    @Autowired
    private ISysRoleTenantService sysRoleTenantService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysProjectService sysProjectService;

    @Override
    public List<String> getRoleTypes(String userId, String tenantCode) {

        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SysRole::getDisabled, 0);
        wrapper.inSql(SysRole::getId, "select a.role_id from sys_role_tenant a, sys_role_user b where a.role_id = b.role_id and a.tenant_code = '" + tenantCode + "' and b.user_id = '" + userId + "'");
        List<SysRole> list = baseMapper.selectList(wrapper);
        List<String> ret = new ArrayList<>();
        for (SysRole role : list) {
            ret.add(role.getRoleType());
        }
        return ret;
    }

    @Override
    public Integer add(SysRole sysRole) throws Exception {
        String userId = RequestHeaderUtils.getUserId(request);
        //未输入角色编码，系统生成编码
        if(StringUtils.isEmpty(sysRole.getRoleCode())){
            String roleCode = ChineseCharacterUtil.convertHanzi2Pinyin(sysRole.getRoleName(), false)+"_"+getRandomValue(8);
            sysRole.setRoleCode(roleCode);
        }
        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        qw.eq(SysRole::getRoleCode, sysRole.getRoleCode());
        qw.eq(SysRole::getDisabled, 0);
        List<SysRole> sysRoles = baseMapper.selectList(qw);
        if (null == sysRole.getId()) {
            if (CollectionUtils.isNotEmpty(sysRoles)) {
                throw new Exception("存在相同的角色码，请重新添加！");
            }
            sysRole.setCreaterId(userId);
            sysRole.setCreateTime(new Date());
            sysRole.setUpdateId(userId);
            sysRole.setUpdateTime(new Date());
            baseMapper.insert(sysRole);

        } else {
            if (CollectionUtils.isNotEmpty(sysRoles) && !sysRoles.get(0).getId().equals(sysRole.getId())) {
                throw new Exception("存在相同的角色码，请重新添加！");
            }
            SysRole sysRole1 = baseMapper.selectById(sysRole.getId());
            BeanUtils.copyPropertiesIgnoreNull(sysRole, sysRole1);
            sysRole.setUpdateId(userId);
            sysRole.setUpdateTime(new Date());
            baseMapper.updateById(sysRole);

        }
        return 1;
    }

    /*产生numSize位16进制的数*/
    public String getRandomValue(int numSize) {
        String str = "";
        for (int i = 0; i < numSize; i++) {
            char temp = 0;
            int key = (int) (Math.random() * 2);
            switch (key) {
                case 0:
                    temp = (char) (Math.random() * 10 + 48);//产生随机数字
                    break;
                case 1:
                    temp = (char) (Math.random() * 6 + 'a');//产生a-f
                    break;
                default:
                    break;
            }
            str = str + temp;
        }
        return str;
    }

    @Override
    public SysRole detail(String id) {
        SysRole sysRole = baseMapper.selectById(id);
        LambdaQueryWrapper<SysRoleUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysRoleUser::getRoleId, id);
        userWrapper.eq(SysRoleUser::getDisabled, 0);
        List<SysRoleUser> sysUsers = sysRoleUserService.list(userWrapper);
        sysRole.setSysRoleUsers(sysUsers);
        LambdaQueryWrapper<SysRoleOrg> orgWrapper = new LambdaQueryWrapper<>();
        orgWrapper.eq(SysRoleOrg::getRoleId, id);
        orgWrapper.eq(SysRoleOrg::getDisabled, 0);
        List<SysRoleOrg> sysRoleOrgs = sysRoleOrgService.list(orgWrapper);
        sysRole.setSysRoleOrgs(sysRoleOrgs);
        LambdaQueryWrapper<SysRoleEqu> equWrapper = new LambdaQueryWrapper<>();
        equWrapper.eq(SysRoleEqu::getRoleId, id);
        equWrapper.eq(SysRoleEqu::getDisabled, 0);
        List<SysRoleEqu> sysRoleEqus = sysRoleEquService.list(equWrapper);
        sysRole.setSysRoleEqus(sysRoleEqus);
        LambdaQueryWrapper<SysRolePermission> permWrapper = new LambdaQueryWrapper<>();
        permWrapper.eq(SysRolePermission::getRoleId, id);
        permWrapper.eq(SysRolePermission::getDisabled, 0);
        List<SysRolePermission> sysRolePermissions = sysRolePermissionService.list(permWrapper);
        sysRole.setSysRolePermissions(sysRolePermissions);
        LambdaQueryWrapper<SysRoleTenant> tenantWrapper = new LambdaQueryWrapper<>();
        tenantWrapper.eq(SysRoleTenant::getRoleId, id);
        tenantWrapper.eq(SysRoleTenant::getDisabled, 0);
        List<SysRoleTenant> sysRoleTenants = sysRoleTenantService.list(tenantWrapper);
        sysRole.setSysRoleTenants(sysRoleTenants);
        return sysRole;
    }

    @Override
    public Integer delete(String id) throws Exception {
        String userId = RequestHeaderUtils.getUserId(request);
        LambdaQueryWrapper<SysRoleUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysRoleUser::getRoleId, id);
        userWrapper.eq(SysRoleUser::getDisabled, 0);
        List<SysRoleUser> sysUsers = sysRoleUserService.list(userWrapper);
        if (CollectionUtils.isNotEmpty(sysUsers)) {
            throw new Exception("当前角色有用户引用，不能停用！");
        }
        LambdaQueryWrapper<SysRoleOrg> orgWrapper = new LambdaQueryWrapper<>();
        orgWrapper.eq(SysRoleOrg::getRoleId, id);
        orgWrapper.eq(SysRoleOrg::getDisabled, 0);
        List<SysRoleOrg> sysRoleOrgs = sysRoleOrgService.list(orgWrapper);
        if (CollectionUtils.isNotEmpty(sysRoleOrgs)) {
            throw new Exception("当前角色有用户引用，不能停用！");
        }
        LambdaQueryWrapper<SysRoleEqu> equWrapper = new LambdaQueryWrapper<>();
        equWrapper.eq(SysRoleEqu::getRoleId, id);
        equWrapper.eq(SysRoleEqu::getDisabled, 0);
        List<SysRoleEqu> sysRoleEqus = sysRoleEquService.list(equWrapper);
        if (CollectionUtils.isNotEmpty(sysRoleEqus)) {
            throw new Exception("当前角色有用户引用，不能停用！");
        }
        LambdaQueryWrapper<SysRolePermission> permWrapper = new LambdaQueryWrapper<>();
        permWrapper.eq(SysRolePermission::getRoleId, id);
        permWrapper.eq(SysRolePermission::getDisabled, 0);
        List<SysRolePermission> sysRolePermissions = sysRolePermissionService.list(permWrapper);
        if (CollectionUtils.isNotEmpty(sysRolePermissions)) {
            throw new Exception("当前角色有用户引用，不能停用！");
        }
        LambdaQueryWrapper<SysRoleTenant> tenantWrapper = new LambdaQueryWrapper<>();
        tenantWrapper.eq(SysRoleTenant::getRoleId, id);
        tenantWrapper.eq(SysRoleTenant::getDisabled, 0);
        List<SysRoleTenant> sysRoleTenants = sysRoleTenantService.list(tenantWrapper);
        if (CollectionUtils.isNotEmpty(sysRoleTenants)) {
            throw new Exception("当前角色有用户引用，不能停用！");
        }
        SysRole sysRole = baseMapper.selectById(id);
        sysRole.setDisabled(1);
        sysRole.setUpdateId(userId);
        sysRole.setUpdateTime(new Date());
        baseMapper.updateById(sysRole);

        return 1;
    }

    @Override
    public IPage<SysRole> getList(String inParam) {
        String userId = RequestHeaderUtils.getUserId(request);

        JSONObject object = JSONObject.parseObject(inParam);
        String tenantCode = object.getString("tenantCode");
        String roleCode = object.getString("roleCode");
        String status = object.getString("status");
        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(tenantCode)) {
            // 只查询该项目下的角色
            qw.inSql(SysRole::getId, "select role_id from sys_role_tenant where disabled=0 and tenant_code='"+tenantCode+"'");
        } else {
            // 查询有权限项目下的角色或者自己创建的角色
            List<SysProject> sysProjects = sysProjectService.getProjectInfoByUserId(userId);
            if (CollectionUtils.isNotEmpty(sysProjects)) {
                StringBuilder builder = new StringBuilder();
                for (SysProject sysProject : sysProjects) {
                    builder.append("'").append(sysProject.getTenantCode()).append("',");
                }
                qw.and(wp -> wp.inSql(SysRole::getId, "select role_id from sys_role_tenant where disabled=0 and tenant_code in ("+builder.substring(0, builder.length()-1)+")").or().eq(SysRole::getCreaterId, userId));
            }
        }
        if (StringUtils.isNotEmpty(roleCode)) {
            qw.eq(SysRole::getRoleCode, roleCode);
        }
        if (StringUtils.isNotEmpty(status)) {
            qw.eq(SysRole::getDisabled, status);
        }
        qw.notLike(SysRole::getRoleCode, "ROLE_SUPER_");
        // 非超管增加权限
//        SysUser sysUser = sysUserService.getById(userId);
//        if (!"0".equals(sysUser.getIsStatus())) {
            // 查询自己所属的角色或自己创建的角色
            qw.and(wq->wq.inSql(SysRole::getId, "select role_id from sys_role_user where disabled=0 and user_id='"+userId+"'").or().eq(SysRole::getCreaterId, userId));
//        }
        qw.orderByAsc(SysRole::getSort);
        qw.orderByDesc(SysRole::getCreateTime);
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPage();
        Integer pageSize = pageDomain.getPageSize();
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        IPage<SysRole> iPage = baseMapper.selectPage(page, qw);

        return iPage;
    }

    @Override
    public Integer startUsing(String id) {
        String userId = RequestHeaderUtils.getUserId(request);
        SysRole sysRole = baseMapper.selectById(id);
        sysRole.setDisabled(0);
        sysRole.setUpdateId(userId);
        sysRole.setUpdateTime(new Date());
        baseMapper.updateById(sysRole);
        return 1;
    }

    @Override
    public List<SysRole> getRoleListByTenantCodeAndOrgCode(String tenantCode, String orgCode) {
        if(StringUtils.isEmpty(tenantCode)){
            return null;
        }
        return baseMapper.getRoleListByTenantCodeAndOrgCode(tenantCode,orgCode);
    }

    @Override
    public SysRole queryRoleByEquId(String equId) {
        return baseMapper.queryRoleByEquId(equId);
    }

    @Override
    public List<SysRole> getRoleListByTenantCode(String tenantCode) {
        String userId = RequestHeaderUtils.getUserId(request);
//        if(StringUtils.isEmpty(tenantCode)){
//            return null;
//        }
        return baseMapper.getRoleListByTenantCode(tenantCode, userId);
    }

    @Override
    public SysRole getByCode(String roleCode) {
        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        qw.eq(SysRole::getRoleCode, roleCode);
        qw.eq(SysRole::getDisabled, 0);
        SysRole sysRole = baseMapper.selectOne(qw);
        return sysRole;
    }

    @Override
    public SysRole dealExpertRole() {
        // 新建角色
        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        qw.eq(SysRole::getRoleCode, "ROLE_EXPERT");
        qw.eq(SysRole::getDisabled, 0);
        SysRole sysRole = baseMapper.selectOne(qw);
        if (null == sysRole) {
            sysRole = new SysRole();
            sysRole.setRoleName("品质工程专家角色");
            sysRole.setRoleCode("ROLE_EXPERT");
            sysRole.setRoleType("1");
            sysRole.setCreaterId("sys");
            sysRole.setUpdateId("sys");
            sysRole.setCreateTime(new Date());
            baseMapper.insert(sysRole);
        }
        return sysRole;
    }

    @Override
    public Map<String, Object> queryRoleByProSecUser(String proCode, String orgId, String uId) {
        return baseMapper.queryRoleByProSecUser(proCode,orgId,uId);
    }
}
